﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Web.UI.DataVisualization.Charting;
using System.Drawing;
using System.Drawing.Imaging;

public partial class WebSite_t_data_clustering : System.Web.UI.Page
{
    class StoredInfo
    {
        public Dictionary<string, int> ProvinceCount; //籍贯省份出现频率
        public Dictionary<string, int> CollegeCount;   //学院出现频率
        public Dictionary<string, int> sex;   //性别出现频率
        public Dictionary<int, int> age;  //年龄出现频率
        public int count;
        public StoredInfo()
        {
            ProvinceCount = new Dictionary<string, int>();
            CollegeCount = new Dictionary<string, int>();
            sex = new Dictionary<string, int>();
            age = new Dictionary<int, int>();
            count = 0;
        }
    };
    string sqlString;
    string collegename, year, grade, Nationality, testname, sex;
    float uplimit, lowlimit, sectionlength;
    int RowsNum;
    StoredInfo[] StoreArray;
    protected void Page_Load(object sender, EventArgs e)
    {
        if (Session["UserId"] == null || Session["UserIdentity"].ToString() != "1")
        {
            Response.Redirect("Default.aspx", false);
            HttpContext.Current.ApplicationInstance.CompleteRequest();
            return;
        }

        if (!IsPostBack)//动态加载分组数量下拉选单
        {
            int i = 1;
            for (; i <= 10; i++)
            {
                ListItem li = new ListItem(i.ToString(), i.ToString());// 构造一项
                PartNumDropDownList.Items.Insert(i - 1, li);//向你的dropDownList中添加一这个项到首位置
            }
        }
    }

    protected void ClusterBtn_Click(object sender, EventArgs e)
    {
        int GroupNum = 0;
        try
        {
            //获取下拉列表数据范围信息
            collegename = CollegeDropDownList.SelectedItem.Text;
            year = TestDateDropDownList.SelectedItem.Text;
            grade = GradeDropDownList.SelectedItem.Text;
            Nationality = NationalityDropDownList.SelectedItem.Text;
            testname = TargetDropDownList.SelectedItem.Text;
            sex = SexDropDownList.SelectedItem.Text;

            //获取分组数量
            GroupNum = int.Parse(PartNumDropDownList.SelectedItem.Text);

            //获得查询SQL语句

            sqlString = "select BornDate,RTRIM(LTrim(Nationality)) AS Nationality,LTRIM(RTRIM(CollegeName)) AS CollegeName,Sex,Grade,LTRIM(RTRIM(ProvinceName)) AS ProvinceName,Result from TestResultDetail ";
            bool IsBegin = false;

            if (collegename != "全部院系")
            {
                IsBegin = true;
                sqlString += "where collegename='" + collegename + "'";
            }
            if (year != "全部")
            {
                if (!IsBegin)
                {
                    IsBegin = true;
                    sqlString += "where ";
                }
                else
                {
                    sqlString += " and ";
                }
                sqlString += "TestDate='" + year + "//1//1'";
            }
            if (grade != "全部年级")
            {
                if (!IsBegin)
                {
                    IsBegin = true;
                    sqlString += "where ";
                }
                else
                {
                    sqlString += " and ";
                }
                sqlString += "grade=" + grade;
            }
            if (Nationality != "全部")
            {
                if (!IsBegin)
                {
                    IsBegin = true;
                    sqlString += " where ";
                }
                else
                {
                    sqlString += " and ";
                }
                sqlString += "Nationality='" + Nationality + "'";
            }
            if (sex != "全部")
            {
                if (!IsBegin)
                {
                    IsBegin = true;
                    sqlString += " where ";
                }
                else
                {
                    sqlString += " and ";
                }
                if (sex == "男")
                {
                    sex = "0";
                }
                else
                {
                    sex = "1";
                }
                sqlString += "sex=" + sex;
            }
            if (!IsBegin)
            {
                IsBegin = true;
                sqlString += " where ";
            }
            else
            {
                sqlString += " and ";
            }
            sqlString += "TestName='" + testname + "'";

            //从数据库里面读取所需信息，填充到DataTable table中去。
            SqlConnection conn = new SqlConnection("Data Source=Localhost;Integrated Security=SSPI;Initial Catalog=CSHDB");
            SqlCommand command = new SqlCommand(sqlString, conn);
            conn.Open();
            SqlDataAdapter adapter = new SqlDataAdapter(command);
            DataTable table = new DataTable();
            adapter.Fill(table);

            //从数据库里面读取testname项的最大值，最小值，以确定每组分界标准。
            sqlString = "select MAX(uplimit) as maxlimit,MIN(lowerlimit) as minlimit from TargetLevel where TestName='" + testname + "'";
            command.CommandText = sqlString;
            SqlDataReader reader = command.ExecuteReader();
            if (reader.HasRows)
            {
                reader.Read();
                uplimit = float.Parse(reader.GetValue(0).ToString());
                lowlimit = float.Parse(reader.GetValue(1).ToString());
            }

            sectionlength = (uplimit - lowlimit) / GroupNum;//每个区间的长度
            RowsNum = table.Rows.Count;
            StoreArray = new StoredInfo[GroupNum];
            for (int i = 0; i < GroupNum; i++)
            {
                StoreArray[i] = new StoredInfo();
            }
            //分别存储每个组的信息到StoreArray中去。
            for (int i = 0; i < RowsNum; i++)
            {
                //获得该数据所属组别0~(GroupNum-1)
                int group = Convert.ToInt32((float.Parse(table.Rows[i]["Result"].ToString()) - lowlimit) / sectionlength);
                if (group < 0)
                {
                    group = 0;
                }
                if (group > GroupNum - 1)
                {
                    group = GroupNum - 1;
                }
                if (StoreArray[group].age.ContainsKey((DateTime.Now.Year - ((DateTime)table.Rows[i]["BornDate"]).Year)))
                {
                    StoreArray[group].age[(DateTime.Now.Year - ((DateTime)table.Rows[i]["BornDate"]).Year)]++;
                }
                else
                    StoreArray[group].age[(DateTime.Now.Year - ((DateTime)table.Rows[i]["BornDate"]).Year)] = 1;
                if (!StoreArray[group].CollegeCount.ContainsKey(table.Rows[i]["CollegeName"].ToString()))
                {
                    StoreArray[group].CollegeCount[table.Rows[i]["CollegeName"].ToString()] = 1;
                }
                else
                    StoreArray[group].CollegeCount[table.Rows[i]["CollegeName"].ToString()]++;
                StoreArray[group].count++;
                if (!StoreArray[group].ProvinceCount.ContainsKey(table.Rows[i]["ProvinceName"].ToString()))
                {
                    StoreArray[group].ProvinceCount[table.Rows[i]["ProvinceName"].ToString()] = 1;
                }
                else
                    StoreArray[group].ProvinceCount[table.Rows[i]["ProvinceName"].ToString()] += 1;
                if (!StoreArray[group].sex.ContainsKey(((table.Rows[i]["Sex"].ToString().ToLower() == "false") ? "男" : "女")))
                {
                    StoreArray[group].sex[((table.Rows[i]["Sex"].ToString().ToLower() == "false") ? "男" : "女")] = 1;
                }
                else
                    StoreArray[group].sex[((table.Rows[i]["Sex"].ToString().ToLower() == "false") ? "男" : "女")] += 1;
            }
            Response.Cache.SetExpires(DateTime.Now.AddSeconds(3));
            Response.Cache.SetCacheability(HttpCacheability.Public);
            Response.Cache.SetValidUntilExpires(true);

            Cache["StoreArray"] = StoreArray;
            Cache["TestName"] = testname;
            Cache["UpLimit"]=uplimit;
            Cache["LowLimit"]=lowlimit;
            Cache["SectionLength"]=sectionlength;
            DrawPie();
        }
        catch (Exception ex)
        {
            //跳转到错误处理页面。
            Session["ErrorMessage"] = ex.Message + "\n Source:" + ex.Source + "\n TargetSite: " + ex.TargetSite.ToString() + "\nStackTrace:" + ex.StackTrace;
            Session["AtPage"] = "t_data_clustering.aspx";
            Response.Redirect("t_error.aspx", false);
            HttpContext.Current.ApplicationInstance.CompleteRequest();
            return;
        }
    }
    protected void Chart1_Click(object sender, ImageMapEventArgs e)
    {
        try
        {
            DrawPie();
            Series series = Chart1.Series["Series1"];
            int pointIndex = int.Parse(e.PostBackValue);

            if (pointIndex >= 0 && pointIndex < series.Points.Count)
            {
                series.Points[pointIndex].CustomProperties += "Exploded=true";
            }
        }
        catch (Exception ex)
        {

            //跳转到错误处理页面。
            Session["ErrorMessage"] = ex.Message + "\n Source:" + ex.Source + "\n TargetSite: " + ex.TargetSite.ToString() + "\nStackTrace:" + ex.StackTrace; 
            Session["AtPage"] = "t_data_clustering.aspx";
            Response.Redirect("t_error.aspx", false);
            HttpContext.Current.ApplicationInstance.CompleteRequest();
            return;
        }
    }
    /// <summary>
    /// 绘制三维饼状图
    /// </summary>
    private void DrawPie()
    {
        try
        {
            Series series = Chart1.Series["Series1"];

            // 设置series性质参数
            series.ChartType = SeriesChartType.Pie;
            series.ShadowOffset = 2;
            series.BorderColor = Color.Tan;

            Chart1.BackImageTransparentColor = Color.Transparent;
	        //饼状图背景皮肤
            Chart1.BorderSkin.SkinStyle = BorderSkinStyle.Sunken;

	        
            // 设置标签说明内容为所占百分比
            series.LegendToolTip = "#PERCENT";

            //设置返回数据
            series.PostBackValue = "#INDEX";

            series.LegendPostBackValue = "#INDEX";
           
            //从缓存里面读取测试信息数据
            if (Cache["TestName"] != null && Cache["UpLimit"] != null && Cache["LowLimit"] != null && Cache["SectionLength"]!=null)
            {
                testname = (string)Cache["TestName"];
                uplimit = (float)Cache["UpLimit"];
                lowlimit = (float)Cache["LowLimit"];
                sectionlength = (float)Cache["SectionLength"];
            }

            Chart1.Titles[0].Text = testname+"聚类分析结果";

            Chart1.ChartAreas["Default"].Area3DStyle.Enable3D = true;

            Chart1.ChartAreas["Default"].Area3DStyle.LightStyle = LightStyle.Simplistic;


            if (Cache["StoreArray"] != null)
            {     
                StoreArray =(StoredInfo[]) Cache["StoreArray"];
                for (int i = 0; i < StoreArray.Length; i++)
                {
                    StoredInfo info = StoreArray[i];
                    DataPoint point = new DataPoint();
                    point.SetValueY(info.count);
                    series.Points.Add(point);
                    series.Points[series.Points.Count - 1].LegendText = "第" + (i + 1).ToString() + "组(" + (lowlimit + sectionlength * (i)).ToString("F02") + "-" + (lowlimit + sectionlength * (i + 1)).ToString("F02") + ")";

                    string CommonString = "第" + i.ToString() + "共同特征:\n学院>=10%\n";
                    foreach (KeyValuePair<string, int> element in info.CollegeCount)
                    {
                        if ((float)element.Value / info.count >= 0.1)
                        {
                            CommonString += element.Key + "  " + ((float)element.Value / info.count).ToString("P02") + "\n";
                        }
                    }
                    CommonString += "性别特征:(>50%)\n";
                    foreach (KeyValuePair<string, int> element in info.sex)
                    {
                        if ((float)element.Value / info.count > 0.5)
                        {
                            CommonString += element.Key + "  " + ((float)element.Value / info.count).ToString("P02") + "\n";
                        }
                    }
                    CommonString += "籍贯特征:(>10%)\n";
                    foreach (KeyValuePair<string, int> element in info.ProvinceCount)
                    {
                        if ((float)element.Value / info.count > 0.1)
                        {
                            CommonString += element.Key + "  " + ((float)element.Value / info.count).ToString("P02") + "\n";
                        }
                    }
                    CommonString += "年龄:(>20%)\n";
                    foreach (KeyValuePair<int, int> element in info.age)
                    {
                        if ((float)element.Value / info.count > 0.2)
                        {
                            CommonString += element.Key.ToString() + "岁   " + ((float)element.Value / info.count).ToString("P02") + "\n";
                        }
                    }
                    
                    series.Points[series.Points.Count - 1].ToolTip = CommonString;
                }
            }

        }
        catch(Exception ex)
        {
            //跳转到错误处理页面。
            Session["ErrorMessage"] = ex.Message + "\n Source:" + ex.Source + "\n TargetSite: " + ex.TargetSite.ToString() + "\nStackTrace:" + ex.StackTrace;
            Session["AtPage"] = "t_data_clustering.aspx";
            Response.Redirect("t_error.aspx", false);
            HttpContext.Current.ApplicationInstance.CompleteRequest();
            return;
        }
      
    }
    /// <summary>
    /// 表格形式显示聚类分析数据
    /// </summary>
    /// <param name="info">存储信息</param>
    /// <param name="num">组别</param>
    /// <returns>表格HTML代码</returns>
    private string BuildTable(StoredInfo info, int num)
    {
        string TableString;
        TableString = "<table class=\"TableStyle\"><tr><td class=\"ColumnLStyle\">项目名</td><td class=\"ColumnRStyle\">";
        TableString += testname + "</td></tr>";
        TableString += "<tr><td class=\"ColumnLStyle\">组数</td><td class=\"ColumnRStyle\">";
        TableString += num.ToString() + "</td></tr>";
        TableString += "<tr><td class=\"ColumnLStyle\">该组数据范围</td><td class=\"ColumnRStyle\">";
        TableString += (lowlimit + sectionlength * (num - 1)).ToString() + "-" + (lowlimit + sectionlength * (num)).ToString() + "</td></tr>";
        TableString += "<tr><td class=\"ColumnLStyle\">该组数据数量</td><td class=\"ColumnRStyle\">";
        TableString += info.count.ToString() + "</td></tr>";
        TableString += "<tr><td class=\"ColumnLStyle\">占总数据比例</td><td class=\"ColumnRStyle\">";
        TableString += ((float)info.count / RowsNum).ToString("P02") + "</td></tr>";
        TableString += "<tr><td class=\"ColumnLStyle\">共同特征</td><td>";
        TableString += "<b>学院:(>=20%)</b><br/>";
        foreach (KeyValuePair<string, int> element in info.CollegeCount)
        {
            if ((float)element.Value / info.count >= 0.2)
            {
                TableString += element.Key + "  " + ((float)element.Value / info.count).ToString("P02") + "<br/>";
            }
        }
        TableString += "<b>性别:(>50%)</b><br/>";
        foreach (KeyValuePair<string, int> element in info.sex)
        {
            if ((float)element.Value / info.count > 0.5)
            {
                TableString += element.Key + "  " + ((float)element.Value / info.count).ToString("P02") + "<br/>";
            }
        }
        TableString += "<b>籍贯:(>20%)</b><br/>";
        foreach (KeyValuePair<string, int> element in info.ProvinceCount)
        {
            if ((float)element.Value / info.count > 0.2)
            {
                TableString += element.Key + "  " + ((float)element.Value / info.count).ToString("P02") + "<br/>";
            }
        }
        TableString += "<b>年龄:(>20%)</b><br/>";
        foreach (KeyValuePair<int, int> element in info.age)
        {
            if ((float)element.Value / info.count > 0.2)
            {
                TableString += element.Key.ToString() + "岁   " + ((float)element.Value / info.count).ToString("P02") + "<br/>";
            }
        }
        TableString += "</td></tr></table>";
        return TableString;
    }
}
